package baseFx.database.where;

import baseFx.common.Action1T;
import baseFx.common.Dynamic;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExecuteWhere<T> {
    private Class<T> table;

    public final Class<T> getTable() {
        return table;
    }

    public ExecuteWhere(Class<T> clazz) {
        table = clazz;
    }

    public ExecuteWhere() {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) type;
            Type clazz = pType.getActualTypeArguments()[0];
            if (clazz instanceof Class) {
                table = (Class<T>) clazz;
            }
        }
    }

    public Integer take() {
        return null;
    }

    public boolean allowEmptyCondition() {
        return true;
    }

    public String splitCondition() {
        return "and";
    }

    public T eq() {
        return null;
    }

    public T neq() {
        return null;
    }

    public T less() {
        return null;
    }

    public T greater() {
        return null;
    }

    public T lessEq() {
        return null;
    }

    public T greaterEq() {
        return null;
    }

    public T like() {
        return null;
    }

    public T notLike() {
        return null;
    }

    public T isNull() {
        return null;
    }

    public T isNotNull() {
        return null;
    }

    public List<T> in() {
        return null;
    }

    public List<T> inOrNull() {
        return null;
    }

    public List<T> notIn() {
        return null;
    }

    public List<T> notInOrNull() {
        return null;
    }

    public String index() {
        return null;
    }

    public ExecuteWhere<T> clone(Action1T<Dynamic> action) {
        Class<T> table = getTable();
        Map<String, Object> map = new HashMap<>(24);
        map.put("allowEmptyCondition", allowEmptyCondition());
        map.put("splitCondition", splitCondition());
        map.put("eq", eq());
        map.put("neq", neq());
        map.put("less", less());
        map.put("greater", greater());
        map.put("greaterEq", greaterEq());
        map.put("lessEq", lessEq());
        map.put("like", like());
        map.put("notLike", notLike());
        map.put("isNull", isNull());
        map.put("isNotNull", isNotNull());
        map.put("in", in());
        map.put("inOrNull", inOrNull());
        map.put("notIn", notIn());
        map.put("notInOrNull", notInOrNull());
        map.put("index", index());
        Dynamic dm = new Dynamic(map);
        action.execute(dm);
        return new ExecuteWhere<T>(table) {
            private Dynamic pm = dm;

            @Override
            public boolean allowEmptyCondition() {
                return pm.getBool("allowEmptyCondition");
            }

            @Override
            public String splitCondition() {
                return pm.getString("splitCondition");
            }

            @Override
            public T eq() {
                return (T) pm.get("eq");
            }

            @Override
            public T neq() {
                return (T) pm.get("neq");
            }

            @Override
            public T less() {
                return (T) pm.get("less");
            }

            @Override
            public T greater() {
                return (T) pm.get("greater");
            }

            @Override
            public T lessEq() {
                return (T) pm.get("lessEq");
            }

            @Override
            public T greaterEq() {
                return (T) pm.get("greaterEq");
            }

            @Override
            public T like() {
                return (T) pm.get("like");
            }

            @Override
            public T notLike() {
                return (T) pm.get("notLike");
            }

            @Override
            public T isNull() {
                return (T) pm.get("isNull");
            }

            @Override
            public T isNotNull() {
                return (T) pm.get("isNotNull");
            }

            @Override
            public List<T> in() {
                return (List<T>) pm.get("in");
            }

            @Override
            public List<T> inOrNull() {
                return (List<T>) pm.get("inOrNull");
            }

            @Override
            public List<T> notIn() {
                return (List<T>) pm.get("notIn");
            }

            @Override
            public List<T> notInOrNull() {
                return (List<T>) pm.get("notInOrNull");
            }

            @Override
            public String index() {
                return pm.getString("index");
            }
        };
    }
}
